# coding: utf-8
#dicionario que contem todos os terminais e seus respectivos codigos
pal_res = {'write':1,'while':2,'until':3,'to':4,'then':5,'string':6,'repeat':7,'real':8,'read':9,'program':10,'procedure':11,
                   'or':12,'of':13,'literal':14,'integer':15,'if':16,'identificador':17,'for':19,'end':20,'else':21,'do':22,
                   'declaravariaveis':23,'const':24,'char':25,'chamaprocedure':26,'begin':27,'array':28,'and':29,'>=':30,'>':31,
                   '=':32,'<>':33,'<=':34,'<':35,'+':36,'_numreal':37,'_numinteiro':38,'_nomestring':39,']':40,'[':41,';':42,':':43,
                   '/':44,'..':45,'.':46,',':47,'*':48,')':49,'(':50, '$':51, '-':52}

#lista de operadores que sao caracteres simples
operadores = [[">=" , ">" , "=" , "<>" , "<=" , "<" , "+" , "/" , ".." , "." , "*" , "-" , ":" , ")" , ";" , "[" , "]"] ,
              ["[" , "]" , "=" , ":" , "," , ";" , "(" , ")" , "."] ]

#variaveis globais do analisador sintatico
a = 0
x = 0
pilha = [51,53]

#variaveis globais para o analisador semantico
nome = ""
nivel = 0

sem = 0

#tabela de identificadores
ident = {}

#matriz de producoes
producoes =    [[10,100,17,42,54,46,0,0,0,0,0,0,0,0,0],##P1
                [55,56,57,58,0,0,0,0,0,0,0,0,0,0],##P2
                [24,101,17,32,104,59,42,60,0,0,0,0,0,0,0,0],##P3
                [18,0,0,0,0,0,0,0,0,0,0,0,0,0],##P4
                [101,17,32,104,59,42,60,0,0,0,0,0,0,0,0,0],##P5
                [18,0,0,0,0,0,0,0,0,0,0,0,0,0],##P6
                [23,61,43,104,59,42,62,0,0,0,0,0,0,0,0],##P7
                [18,0,0,0,0,0,0,0,0,0,0,0,0,0],##P8
                [102,17,63,0,0,0,0,0,0,0,0,0,0,0,0],##P9
                [47,102,17,63,0,0,0,0,0,0,0,0,0,0,0],##P10
                [18,0,0,0,0,0,0,0,0,0,0,0,0,0],##P11
                [61,43,104,59,42,62,0,0,0,0,0,0,0,0,0],##P12
                [18,0,0,0,0,0,0,0,0,0,0,0,0,0],##P13
                [28,41,38,45,38,40,13,104,64,0,0,0,0,0,0],##P14
                [15,0,0,0,0,0,0,0,0,0,0,0,0,0],##P15
                [25,0,0,0,0,0,0,0,0,0,0,0,0,0],##P16
                [6,0,0,0,0,0,0,0,0,0,0,0,0,0],##P17
                [8,0,0,0,0,0,0,0,0,0,0,0,0,0],##P18
                [15,0,0,0,0,0,0,0,0,0,0,0,0,0],##P19
                [25,0,0,0,0,0,0,0,0,0,0,0,0,0],##P20
                [6,0,0,0,0,0,0,0,0,0,0,0,0,0],##P21
                [8,0,0,0,0,0,0,0,0,0,0,0,0,0],##P22
                [11,103,17,107,65,57,58,42,55,0,0,0,0,0,0,0],##P23
                [18,0,0,0,0,0,0,0,0,0,0,0,0,0],##P24
                [50,61,43,104,59,42,62,49,0,0,0,0,0,0,0],##P25
                [18,0,0,0,0,0,0,0,0,0,0,0,0,0],##P26
                [27,66,67,106,20,0,0,0,0,0,0,0,0,0,0],##P27
                [42,66,67,0,0,0,0,0,0,0,0,0,0,0],##P28
                [18,0,0,0,0,0,0,0,0,0,0,0,0,0],##P29
                [16,41,68,40,5,27,66,20,69,0,0,0,0,0],##P30
                [2,41,68,40,22,27,66,20,0,0,0,0,0,0],##P31
                [7,66,3,41,68,40,0,0,0,0,0,0,0,0],##P32
                [9,50,70,71,49,0,0,0,0,0,0,0,0,0],##P33
                [26,200,17,201,72,0,0,0,0,0,0,0,0,0,0,0],##P34
                [1,50,73,74,49,0,0,0,0,0,0,0,0,0],##P35
                [19,41,202,17,32,108,68,40,4,41,108,68,40,22,27,66,20],##P36
                [18,0,0,0,0,0,0,0,0,0,0,0,0,0],##P37
                [50,61,49,0,0,0,0,0,0,0,0,0,0,0],##P38
                [18,0,0,0,0,0,0,0,0,0,0,0,0,0],##P39
                [14,0,0,0,0,0,0,0,0,0,0,0,0,0],##P40
                [68,0,0,0,0,0,0,0,0,0,0,0,0,0],##P41
                [47,73,74,0,0,0,0,0,0,0,0,0,0,0],##P42
                [18,0,0,0,0,0,0,0,0,0,0,0,0,0],##P43
                [75,76,77,0,0,0,0,0,0,0,0,0,0,0],##P44
                [78,79,0,0,0,0,0,0,0,0,0,0,0,0],##P45
                [38,0,0,0,0,0,0,0,0,0,0,0,0,0],##P]46
                [203,17,0,0,0,0,0,0,0,0,0,0,0,0,0],##P47
                [39,0,0,0,0,0,0,0,0,0,0,0,0,0],##P48
                [37,0,0,0,0,0,0,0,0,0,0,0,0,0],##P49
                [50,68,49,0,0,0,0,0,0,0,0,0,0,0],##P50
                [32,80,0,0,0,0,0,0,0,0,0,0,0,0],##P51
                [35,80,0,0,0,0,0,0,0,0,0,0,0,0],##P52
                [31,80,0,0,0,0,0,0,0,0,0,0,0,0],##P53
                [30,80,0,0,0,0,0,0,0,0,0,0,0,0],##P54
                [34,80,0,0,0,0,0,0,0,0,0,0,0,0],##P55
                [33,80,0,0,0,0,0,0,0,0,0,0,0,0],##P56
                [18,0,0,0,0,0,0,0,0,0,0,0,0,0],##P57
                [36,75,76,0,0,0,0,0,0,0,0,0,0,0],##P58
                [52,75,76,0,0,0,0,0,0,0,0,0,0,0],##P59
                [75,76,0,0,0,0,0,0,0,0,0,0,0,0],##P60
                [36,75,76,0,0,0,0,0,0,0,0,0,0,0],##P61
                [52,75,76,0,0,0,0,0,0,0,0,0,0,0],##P62
                [12,75,76,0,0,0,0,0,0,0,0,0,0,0],##P63
                [18,0,0,0,0,0,0,0,0,0,0,0,0,0],##P64
                [48,78,79,0,0,0,0,0,0,0,0,0,0,0],##P65
                [44,78,79,0,0,0,0,0,0,0,0,0,0,0],##P66
                [29,78,79,0,0,0,0,0,0,0,0,0,0,0],##P67
                [18,0,0,0,0,0,0,0,0,0,0,0,0,0],##P68
                [21,27,66,20,0,0,0,0,0,0,0,0,0,0],##P69
                [18,0,0,0,0,0,0,0,0,0,0,0,0,0],##P70
                [204,17,0,0,0,0,0,0,0,0,0,0,0,0,0],##P71
                [47,70,71,0,0,0,0,0,0,0,0,0,0,0],##P72
                [18,0,0,0,0,0,0,0,0,0,0,0,0,0]] ##P73

for producao in producoes:
    producao.reverse()
#matriz de parsing
parsing = {"53,10":1,"54,11":2,"54,23":2,"54,24":2,"54,27":2,"55,11":23,"55,23":24,"55,24":24,"55,27":24,"56,23":4,"56,24":3,
           "56,27":4,"57,23":7,"57,27":8,"58,27":27,"59,6":21,"59,8":22,"59,15":19,"59,25":20,"59,28":14,"60,17":5,"60,23":6,
           "60,27":6,"61,17":9,"62,17":12,"62,27":13,"62,49":13,"63,43":11,"63,47":10,"63,49":11,"64,6":17,"64,8":18,"64,15":15,
           "64,25":16,"65,23":26,"65,27":26,"65,50":25,"66,1":35,"66,2":31,"66,3":37,"66,7":32,"66,9":33,"66,16":30,"66,19":36,
           "66,20":37,"66,26":34,"66,42":37,"67,20":24,"67,42":28,"68,17":44,"68,37":44,"68,38":44,"68,39":44,"68,50":44,"69,3":70,
           "69,20":70,"69,21":69,"69,42":70,"70,17":71,"71,47":72,"71,49":73,"72,3":39,"72,20":39,"72,42":39,"72,50":38,"73,14":40,
           "73,17":41,"73,37":41,"73,38":41,"73,39":41,"73,50":41,"74,47":42,"74,49":43,"75,17":45,"75,37":45,"75,38":45,"75,39":45,
           "75,50":45,"76,12":63,"76,30":64,"76,31":64,"76,32":64,"76,33":64,"76,34":64,"76,35":64,"76,36":61,"76,40":64,"76,47":64,
           "76,49":64,"76,52":62,"77,30":54,"77,31":53,"77,32":51,"77,33":56,"77,34":55,"77,35":52,"77,40":57,"77,47":57,"77,49":57,
           "78,17":47,"78,37":49,"78,38":46,"78,39":48,"78,50":50,"79,12":68,"79,29":67,"79,30":68,"79,31":68,"79,32":68,"79,33":68,
           "79,34":68,"79,35":68,"79,36":68,"79,40":68,"79,44":66,"79,47":68,"79,48":65,"79,49":68,"79,52":68,"80,17":60,"80,36":58,
           "80,37":60,"80,38":60,"80,39":60,"80,50":60,"80,52":59}

#funcao para mostrar mensagem para o usuario, de acordo com o tipo
def mostraMensagem(mensagem, token="", numlinha = 0, codigo = 0):
        if (mensagem == "normal"):
                print "Linha: %2s  ->  Codigo: %2s  ->  Token: %s" % (numlinha, codigo, token)

        elif (mensagem == "fim"):
                print "Linha: %2s  ->  Codigo: %2s  ->  Token: Fim de arquivo." % (numlinha, codigo)                

        elif (mensagem == "float"):
                print "Erro lexico: numero escrito de maneira incorreta. ->  Linha: %2s  -> Token: %s" % (numlinha, token)
                
        elif (mensagem == "tamanho"):
                print "Erro lexico: tamanho de variavel excedido. ->  Linha: %2s  -> Token: %-15s" % (numlinha, token)

        elif (mensagem == "desconhecido"):
                print "Erro lexico: identificador digitado nao e valido. ->  Linha: %2s  -> Token: %-15s" % (numlinha, token)

        elif (mensagem == "literal"):
                print "Erro lexico: literal nao fechado corretamente. ->  Linha: %2s " % (numlinha)

        elif (mensagem == "string"):
                print "Erro lexico: string nao fechada corretamente. ->  Linha: %2s " % (numlinha)
                
        elif (mensagem == "comentario"):
                print "Erro lexico: comentario de bloco nao fechado corretamente."

        elif (mensagem == "sintatico"):
                print "Erro sintatico na linha %2s." % (numlinha)

        elif (mensagem == "repetido"):
                print "Erro semantico na linha %2s: identificador repetido. Token %s." % (numlinha, token)

        elif (mensagem == "invalido"):
                print "Erro semantico na linha %2s: digito invalido. Token %s." % (numlinha, token)

        elif (mensagem == "inexistente"):
                print "Erro semantico na linha %2s: procedure ou variavel inexistente. Token %s." % (numlinha, token)

        elif (mensagem == "tipovariavel"):
                print "Erro semantico na linha %2s: tipo de variavel invalido. Token %s." % (numlinha, token)                 
                
#funcao do analisador lexico
def analisadorLexico(arquivo):                  
        numlinha = 0
        flag_comment = False #flag para comentario de bloco
        flag_literal = False #flag para literal
        flag_string = False #flag para string

        #faz um laco no arquivo lido, da primeira a ultima linha            
        for linha in arquivo:           
                numlinha += 1                    
                tokens = linha.replace("\n","").replace("\r","").lstrip().split(" ")
                literal = ""

                #verifica se as flags de literal ou string foram inicializadas
                if not flag_literal and not flag_string:
        
                        #faz um laco na linha do programa, do primeiro ao ultimo token da linha
                        for token in tokens:            

                            #se nao foram inicializadas as flags de literal ou string (nao foi encontrado inicio de string ou literal)               
                            if not flag_literal and not flag_string:

                                #se a flag de comentario nao foi inicializada (nao foi encontrado inicio de comentario de bloco)
                                if not flag_comment:                                

                                        #se for um espaco ignora
                                        if token == '':
                                                continue

                                        #se for uma palavra reservada classifica
                                        if pal_res.has_key(token):
                                                if analisadorSintatico(numlinha, pal_res[token], token):                                                    
                                                    mostraMensagem("normal", token, numlinha, pal_res[token])
                                                
                                                else:
                                                    global sem
                                                    if sem > 0:
                                                        return False
                                                    else:
                                                        mostraMensagem("sintatico", token, numlinha)
                                                        return False

                                        #se for um numero inteiro classifica
                                        elif token.isdigit():
                                                if analisadorSintatico(numlinha, pal_res['_numinteiro'], token):                                                   
                                                    mostraMensagem("normal", token, numlinha, pal_res['_numinteiro'])

                                                elif analisadorSintatico(numlinha, pal_res['_numinteiro'], token) == 'semantico':
                                                    return False
                                                
                                                else:
                                                    if sem > 0:
                                                        return False
                                                    else:
                                                        mostraMensagem("sintatico", token, numlinha)
                                                        return False                                                

                                        #se comecar com parenteses () ou conchetes [] classifica
                                        elif token.startswith("(") or token.startswith("[") or token.startswith(")") or token.startswith("]"):
                                                tokens.insert((tokens.index(token)+1),token[0])
                                                tokens.insert((tokens.index(token)+2),token[1:])

                                        #se terminar com parenteses () ou conchetes [] classifica
                                        elif token.endswith(")")  or token.endswith("]") or token.startswith("(") or token.startswith("["):
                                                tokens.insert((tokens.index(token)+1),token[:-1])
                                                tokens.insert((tokens.index(token)+2),token[-1])

                                        #se houver apenas numeros e virgula classifica como numero real
                                        elif token[0].isdigit() and token.rfind(",") != -1 and (token.replace(",","0")).isdigit():
                                                posicaoVirgula = token.rfind(",")
                                                if not token.endswith(","):
                                                        if (token[:posicaoVirgula].isdigit() and token[(posicaoVirgula+1):].isdigit()):
                                                            if analisadorSintatico(numlinha, pal_res['_numreal'], token):                                                   
                                                                mostraMensagem("normal", token, numlinha, pal_res['_numreal'])
                                                                
                                                            else:
                                                                if sem > 0:
                                                                    return False
                                                                else:
                                                                    mostraMensagem("sintatico", token, numlinha)
                                                                    return False 
                                                        else:                                                                                                                      
                                                           mostraMensagem("float", token, numlinha)
                                                           return False
                                                else:                                                   
                                                   mostraMensagem("float", token, numlinha)
                                                   return False

                                        #se for um numero mas houver outros caracteres vai analisando e classificando
                                        elif token[0].isdigit() and not token.isdigit():
                                                num = ""
                                                for char in token:
                                                    if char.isdigit():
                                                        num = num + char

                                                    elif char in operadores[0]:
                                                        if token.index(char)== len(token)-1:
                                                            op = char                                                   
                                                            tokens.insert((tokens.index(token)+1),num)
                                                            tokens.insert((tokens.index(token)+2),op)
                                                            break

                                                        elif token[token.index(char)+1] in operadores[0]:
                                                            op = char + token[(token.find(char))+1]   
                                                            tokens.insert((tokens.index(token)+1),num)
                                                            tokens.insert((tokens.index(token)+2),op)
                                                            tokens.insert((tokens.index(token)+3),token[(token.index(char))+2:])
                                                            break

                                                        else:
                                                            op = char                                                   
                                                            tokens.insert((tokens.index(token)+1),num)
                                                            tokens.insert((tokens.index(token)+2),op)
                                                            tokens.insert((tokens.index(token)+3),token[(token.index(char))+1:])
                                                            break

                                                    elif char == ",":
                                                        num = num + char

                                                    else:
                                                        num = num + char
                                                        mostraMensagem("float", num, numlinha)
                                                        return False

                                        #se comecar com /* ignora, pois e comentario de bloco
                                        elif token.startswith("/*"):
                                                flag_comment = True                                     

                                        #se comecar com // ignora, pois e comentario de linha
                                        elif token.startswith("//"):   
                                                break                                

                                        #se comecar com " ele le e muda a flag_literal para true. Se o literal tiver apenas uma palavra, classifica
                                        elif token.startswith("\""):
                                                if token.endswith("\"") and len(token) != 1: 
                                                    if analisadorSintatico(numlinha, pal_res['literal'], token):                                                    
                                                        mostraMensagem("normal", token, numlinha, pal_res['literal'])
                                                    else:
                                                        if sem > 0:
                                                            return False
                                                        else:
                                                            mostraMensagem("sintatico", token, numlinha)
                                                            return False
                                                else:
                                                   flag_literal = True
                                                   literal = token

                                        #se comecar com ' ele le e muda a flag_string para true. Se a string tiver apenas uma palavra, classifica
                                        elif token.startswith("'"):
                                                if token.endswith("'") and len(token) != 1: 
                                                    if analisadorSintatico(numlinha, pal_res['_nomestring'], token):                                                    
                                                        mostraMensagem("normal", token, numlinha, pal_res['_nomestring'])
                                                    else:
                                                        if sem > 0:
                                                            return False
                                                        else:
                                                            mostraMensagem("sintatico", token, numlinha)
                                                            return False
                                                else:
                                                   flag_string = True
                                                   literal = token                                 

                                        #se comecar com um caracter simples ve se o segundo tambem eh e classifica de acordo com o que encontrar
                                        elif token[0] in operadores[0]:
                                            if token[1] in operadores[0] and token[1] != token[0]:
                                                op = token[0:2]
                                                tokens.insert((tokens.index(token)+1) , op)
                                                tokens.insert((tokens.index(token)+2) , token[2:])

                                            else:
                                                op = token[0]
                                                tokens.insert((tokens.index(token)+1) , op)
                                                tokens.insert((tokens.index(token)+2) , token[1:])

                                        #se comecar com letra le ate encontrar um caracter simples (terminal)
                                        elif token[0].isalpha() and not token.isalnum():
                                                ident = ""
                                                for char in token:
                                                    if char.isalpha():
                                                        ident = ident + char

                                                    elif char in operadores[1]:
                                                        tokens.insert((tokens.index(token)+1),ident)
                                                        tokens.insert((tokens.index(token)+2),char)
                                                        tokens.insert((tokens.index(token)+3),token[(token.index(char))+1:])
                                                        break

                                                    elif char.isdigit():
                                                        ident = ident + char

                                                    else:
                                                        ident = ident + char
                                                        mostraMensagem("desconhecido", ident, numlinha)
                                                        return False
                                                
                                        #se for uma palavra normal mas nao e uma palavra reservada classifica como identificador
                                        elif not pal_res.has_key(token) and len(token) < 10:
                                                if token[0].isdigit() or not token.isalnum(): 
                                                    mostraMensagem("desconhecido", token, numlinha)
                                                    return False
                                                else:
                                                    if analisadorSintatico(numlinha, pal_res['identificador'], token) == True:
                                                        mostraMensagem("normal", token, numlinha, pal_res['identificador'])                                                   
                                                    else:
                                                        if sem > 0:
                                                            return False
                                                        else:
                                                            mostraMensagem("sintatico", token, numlinha)
                                                            return False
                                                    

                                        #se a variavel tiver mais que 10 caracteres da um erro de tamanho
                                        elif len(token) > 10:
                                                if token[0].isdigit() or not token.isalnum():
                                                    mostraMensagem("desconhecido", token, numlinha)
                                                    return False
                                                else:
                                                    mostraMensagem("tamanho", token, numlinha)
                                                    return False

                                #se foi inicializada a flag de comentario de bloco le ate encontrar o fim e ignora
                                else:
                                  if token.endswith("*/"): 
                                      flag_comment = False
                                  else:
                                      continue

                            #se foi inicializadas algumas das flags (literal ou string) ele testa qual eh e le ate
                            #encontrar o caracter correspondente e classifica
                            else:
                                if flag_literal:
                                    for char in token:
                                        if char != "\"":
                                            literal = literal + char
                                        else:
                                            flag_literal = False
                                            literal = literal + char
                                            
                                            if analisadorSintatico(numlinha, pal_res['literal'], token):                                                    
                                                mostraMensagem("normal", literal, numlinha, pal_res['literal'])
                                            else:
                                                if sem > 0:
                                                    return False
                                                else:
                                                    mostraMensagem("sintatico", literal, numlinha)
                                                    return False
                                            
                                            tokens.insert((tokens.index(token)+1),token[(token.index(char))+1:])
                                else:
                                   for char in token:
                                        if char != "'":
                                            literal = literal + char
                                        else:
                                            flag_string = False
                                            literal = literal + char
                                            if analisadorSintatico(numlinha, pal_res['_nomestring'], token):                                                    
                                               mostraMensagem("normal", literal, numlinha, pal_res['_nomestring'])
                                            else:
                                                if sem > 0:
                                                    return False
                                                else:
                                                    mostraMensagem("sintatico", literal, numlinha)
                                                    return False                                

                            literal = literal + " "
                else:
                    if flag_literal:
                           mostraMensagem("literal", token, numlinha)
                           return False
 
                    elif flag_string:
                           mostraMensagem("string" , token , numlinha)
                           return False    

    
        #se a leitura do arquivo terminou e alguma flag nao foi fechada (False) da um erro, de acordo com a flag                
        if flag_comment:
           mostraMensagem("comentario")
           return False
        
        if analisadorSintatico(numlinha, pal_res['$'], token):                                                    
           mostraMensagem("fim", token, numlinha, pal_res['$'])
        else:
            if sem > 0:
                return False
            else:
                mostraMensagem("sintatico", token, numlinha+1)
                return False
        
        return True

#funcao do analisador sintatico
def analisadorSintatico (numlinha, codigo, token):
        x = pilha[-1]
        a = codigo
        while pilha[-1] != 51:
            if pilha[-1] != 0:
                if x == 18: 
                   pilha.pop()
                   x = pilha[-1]
                elif x <= 52:
                   if x == a:
                        pilha.pop()
                        return True
                   else:
                        return False
                    
                elif x >= 100:
                    if analisadorSemantico (numlinha, codigo, token, x):
                        pilha.pop()
                        x = pilha[-1]
                    else:
                        pilha.pop()
                        x = pilha[-1]
                        global sem
                        sem = 1
                        return False

                else:                   
                   key = '%s,%s' %(x,a)
                   if parsing.has_key(key):
                       pilha.pop()
                       prod = parsing[key]
                       pilha.extend(producoes[prod-1])
                       x = pilha[-1]
                   else:
                       return False
            else:
                pilha.pop()
                x = pilha[-1]        
        return True
        

#funcao do analisador semantico
def analisadorSemantico (numlinha, codigo, token, x):
        if x == 100: #identificador program
            ident[token] = dict([('tipo','program') , ('classe','variavel') , ('nivel',0)])
            return True
        
        elif x == 101: #identificador constante
            if not ident.has_key(token):
                global nivel
                ident[token] = dict([('tipo','') , ('classe','const') , ('nivel',nivel)])
                global nome
                nome = token
                return True
            else:
                mostraMensagem('repetido',token, numlinha)
                return False

        elif x == 102: #identificador variavel
            if not ident.has_key(token):
                ident[token] = dict([('tipo','') , ('classe','variavel') , ('nivel',nivel)])
                nome = token
                return True
            else:
                mostraMensagem('repetido',token, numlinha)
                return False

        elif x == 103: #identificador procedure
            if not ident.has_key(token):
                ident[token] = dict([('tipo','') , ('parametros','') , ('classe','procedure') , ('nivel',nivel)])
                nome = token                
                nivel = nivel + 1
                return True
            else:
                mostraMensagem('repetido',token, numlinha)
                return False

        elif x == 104: #tipo do identificador
            ident[nome]['tipo'] = token
            return True
        
        elif x == 106: #zera o nivel
            nivel = nivel - 1
            return True
        
        elif x == 107: #teste de parametros
            if codigo == 65:
               ident[nome]['parametros'] = 'sim'
            else:
               ident[nome]['parametros'] = 'nao'   
            return True
               
        elif x == 108: #testa se e um numero inteiro
            if token.isdigit():
                return True
            else:
                mostraMensagem('invalido',token, numlinha)
                return False
                           
        if x == 200: #verifica identificador procedure na tabela
            if ident.has_key(token):
                nome = token
                return True
            else:
                mostraMensagem('inexistente',token, numlinha)
                return False
            
        elif x == 201: #verifica parametros da procedure
            if codigo == 72:
                if ident[nome]['parametros'] == 'sim':
                    return True
                else:
                    print "Erro semantico na linha %s: parametros incorretos. Token %s." %(numlinha, token)
                    return False
            else:
                if ident[nome]['parametros'] == 'nao':
                    return True
                else:
                    print "Erro semantico na linha %s: parametros incorretos. Token %s." %(numlinha, token)
                    return False
                
        elif x == 202: #verifica identificador variavel do for
            if ident.has_key(token):
                if ident[token]['tipo'] == 'integer':
                    if ident[token]['classe'] == 'variavel':
                        return True
                    else:
                        print "Erro semantico na linha %s: variavel de classe nao aceita. Token %s." % (numlinha, token)
                        return False
                else:
                    mostraMensagem('tipovariavel',token, numlinha)
                    return False
            else:
                mostraMensagem('inexistente',token, numlinha)
                return False
            
        elif x == 204: #verifica se foi declarada variavel simples
            if ident.has_key(token):
                if ident[token]['nivel'] == nivel or ident[token]['nivel'] == 0:
                    if ident[token]['classe'] == 'variavel':
                        return True
                    else:
                        mostraMensagem('tipovariavel',token, numlinha)
                        return False
                else:
                    print "Erro semantico na linha %s: variavel nao declarada no bloco ou globalmente. Token %s." % (numlinha, token)
                    return False
            else:
                mostraMensagem('inexistente',token, numlinha)
                return False
                       
#main             
if __name__ == "__main__":
        try:
                print "Digite o nome do arquivo a ser lido: "
                arq = raw_input()
                arquivo = open(arq, 'r').readlines()                    
              
                if analisadorLexico(arquivo):                       
                   print "Analise concluida."
                   
                else:
                   print "Programa encerrado."
                   
                raw_input()
        except (IOError):
                print "O arquivo nao existe no diretorio atual." 